package stu.khy.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.usertype.ParameterizedType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import stu.khy.dao.BaseDao;

//继承HibernateDaoSupport 减少编码的
@SuppressWarnings("unchecked")
public abstract class BaseHibernateDaoSupport<T> extends HibernateDaoSupport implements BaseDao<T> {
	/*
	 * @Autowired private HibernateTemplate hibernateTemplate;
	 */
	
	@Resource  
    public void setSessionFacotry(SessionFactory sessionFacotry) {  
        super.setSessionFactory(sessionFacotry);  
    } 

	@Override
	public void save(T instance) {
		this.getHibernateTemplate().save(instance);
		/* hibernateTemplate.save(instance); */
		/* this.getSession(true).clear(); */
	}

	@Override
	public void update(T instance) {
		this.getHibernateTemplate().update(instance);
	}

	@Override
	public void saveOrUpdate(T instance) {
		this.getHibernateTemplate().saveOrUpdate(instance);
	}

	@Override
	public T merage(T instance) {
		return this.getHibernateTemplate().merge(instance);
	}

	@Override
	public void delete(T instance) {
		this.getHibernateTemplate().delete(instance);
	}

	@Override
	public void delete(Collection<T> instance) {
		this.getHibernateTemplate().deleteAll(instance);

	}

	@Override
	public Integer delete(final Class<T> cls, final Object[] ids) {
		return this.getHibernateTemplate().execute(new HibernateCallback<Integer>() {

			@Override
			public Integer doInHibernate(Session session) throws HibernateException {
				String hql = "delete from " + cls.getSimpleName() + " where id in(:ids)";
				return session.createQuery(hql).setParameterList("ids", ids).executeUpdate();

			}

			/*
			 * public Integer doInHibernate(Session arg0) throws HibernateException,
			 * SQLException {
			 * 
			 * String hql="delete from "+ cls.getSimpleName()+" where id in(:ids)"; return
			 * arg0.createQuery(hql).setParameterList("ids", ids).executeUpdate(); }
			 */

		});
	}

	@Override
	public T get(Class<T> cls, Serializable id) {
		return this.getHibernateTemplate().get(cls, id);
	}

	@Override
	public List<T> findAll(Class<T> cls) {
		// TODO Auto-generated method stub
		return (List<T>) this.getHibernateTemplate().find("from "+cls.getSimpleName());
	}

	@Override
	public <E> List<E> findForPage(final String hql,final int pageNo,final int pageSize,final Object... values) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().execute(new HibernateCallback<List<E>>() {
			@Override
			public List<E> doInHibernate(Session session) throws HibernateException {
				Query query=session.createQuery(hql);
				if(values !=null &&values.length !=0) {
					for (int i = 0; i < values.length; ++i) {
						query.setParameter(i, values[i]);
					}	
				}
				//query.setProperties(bean);
				query.setFirstResult((pageNo-1)*pageSize);
				query.setMaxResults(pageSize);
				return query.list();
			}
		});
	}

	@Override
	public Number getTotalCount(String hql, Object... values) {
		if(hql.startsWith("select")) {
			hql = "select count(*) " + hql.substring(hql.indexOf(" from ")+1);
		}else {
			hql ="select count(*) " +hql;
		}
		
		
		return (Number) this.getHibernateTemplate().find(hql, values).get(0);
	}

	@Override
	public <E> List<E> find(String hql, Object... values) {
		
		return (List<E>) this.getHibernateTemplate().find(hql, values);
	}

}
